package com.minibobbo.utilities.spe;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.tiled.TileAtlas;
import com.badlogic.gdx.graphics.g2d.tiled.TileMapRenderer;
import com.badlogic.gdx.graphics.g2d.tiled.TiledLoader;
import com.badlogic.gdx.graphics.g2d.tiled.TiledMap;
import com.badlogic.gdx.utils.Array;

public class SpeMap {

	private TileMapRenderer mapRender;
	public TiledMap map;
	private TileAtlas atlas;

	private SimplePlatformEngine parentEngine;

	private OrthographicCamera cam;

	// Should a layer collide or be drawn?
	boolean[] collisionLayers;
	boolean[] drawLayers;

	public SpeMap() {

	}

	public SpeMap(SimplePlatformEngine parentEngine) {
		this.parentEngine = parentEngine;

	}

	/**
	 * Sets the map for this level. The map name should be the name and path of
	 * the tmx file. For instance, "data/levels/level1" THE TEXTURE ATLAS
	 * GENERATED BY THE PACKING PROCESS SHOULD BE IN THE SAME DIRECTORY AS THE
	 * .TMX FILE (e.g. data/levels)
	 * 
	 * @param mapName
	 *            The name and path of the map.
	 */
	public void setMap(String mapName) {
		map = new TiledLoader().createMap(Gdx.files.internal(mapName + ".tmx"));
		String path = mapName;

		int temp = path.lastIndexOf("/");
		if (path.lastIndexOf("/") != -1)
			path = path.substring(0, temp);
		else
			path = "";
		atlas = new TileAtlas(map, Gdx.files.internal(path));
		mapRender = new TileMapRenderer(map, atlas, 4, 4, 1, 1);
		collisionLayers = new boolean[map.layers.size()];
		drawLayers = new boolean[map.layers.size()];
		for (int i = 0; i < collisionLayers.length; i++) {
			collisionLayers[i] = true;
			drawLayers[i] = true;
		}
		Gdx.app.log("Map layers", collisionLayers.length + "");
	}

	public void setCamera(OrthographicCamera cam) {
		this.cam = cam;
	}

	public void drawMap() {
		int[] x = { 0 };
		mapRender.render(cam, x);
	}

	public void drawMapLayer(int layer) {
		if (map.layers.size() > layer) {
			int[] x = { layer };
			mapRender.render(cam, x);
		}
	}

	/**
	 * Searches through the map and finds out if the spot has a tile placed on a
	 * layer marked for collisions.
	 * 
	 * @param x
	 *            X location in world units
	 * @param y
	 *            Y location in world units
	 * @return True if the location is marked for collisions or is outside the
	 *         map. False if it is open.
	 */
	public boolean getTileContact(float x, float y) {
		int xx = (int) x;
		int yy = (int) y;
		if (xx < 0 || xx > map.width - 1 || yy < 0 || yy > map.height - 1) {
			Gdx.app.log("Out of map", "");
			return true;
		}

		for (int i = 0; i < collisionLayers.length; i++) {
			if (collisionLayers[i]) {
				if (map.layers.get(i).tiles[map.height - yy - 1][xx] != 0)
					return true;
			}
		}
		return false;
	}

	/**
	 * Gets the information from the topmost tile in a map.
	 * 
	 * @param x
	 *            X location in world units.
	 * @param y
	 *            Y location in world units.
	 * @return The tile identification of the uppermost tile. -999 if out of
	 *         map.
	 */
	public int getTileInformation(float x, float y) {
		int xx = (int) x;
		int yy = (int) y;
		if (xx < 0 || xx > map.width - 1 || yy < 0 || yy > map.height - 1) {
			Gdx.app.log("Out of map", "");
			return -999;
		}

		// Loop through the layers starting at the top and working our way down.
		for (int i = collisionLayers.length - 1; i >= 0; i--) {
			if (map.layers.get(i).tiles[map.height - yy - 1][xx] != 0)
				return map.layers.get(i).tiles[map.height - yy - 1][xx];
		}
		return 0;
	}

	/**
	 * Returns the tile information from a specific layer.
	 * 
	 * @param x
	 *            X location in world units.
	 * @param y
	 *            Y location in world units.
	 * @param layer
	 *            Layer to search.
	 * @return Value of the tile. -999 if out of the map or on a layer that
	 *         doesn't exist.
	 */
	public int getTileInformation(float x, float y, int layer) {
		int xx = (int) x;
		int yy = (int) y;
		if (xx < 0 || xx > map.width - 1 || yy < 0 || yy > map.height - 1) {
			Gdx.app.log("Out of map", "");
			return -999;
		}
		if (layer < 0 || layer >= collisionLayers.length)
			return -999;

		return map.layers.get(layer).tiles[map.height - yy - 1][xx];
	}

	/**
	 * Sets a layer of the map to collide with dynamic objects. By default this
	 * is true.
	 * 
	 * @param layer
	 *            The layer to change
	 * @param collide
	 *            Should this layer collide?
	 * @return True if we could set the layer to collide. Otherwise, false (e.g.
	 *         there is no layer with this number)
	 */
	public boolean setCollisionLayer(int layer, boolean collide) {
		if (map.layers.size() > layer) {
			collisionLayers[layer] = collide;
			return true;
		} else
			return false;
	}

}
